<template>
  <div class="container">
    <h1>Vue3 readonly 与 shallowReadonly 示例</h1>

    <!-- readonly 示例 -->
    <section class="example-section">
      <h2>readonly 示例</h2>
      <p>readonly 创建一个只读的响应式代理，深层嵌套的对象也是只读的。</p>
      
      <div class="state-display">
        <h3>原始状态 (可变):</h3>
        <pre>{{ JSON.stringify(originalState, null, 2) }}</pre>
        
        <h3>readonly 状态 (只读):</h3>
        <pre>{{ JSON.stringify(readonlyState, null, 2) }}</pre>
        
        <div class="controls">
          <button @click="modifyOriginal">修改原始状态</button>
          <button @click="tryModifyReadonly">尝试修改readonly状态</button>
          <button @click="tryModifyReadonlyNested">尝试修改readonly嵌套对象</button>
        </div>
      </div>
    </section>

    <!-- shallowReadonly 示例 -->
    <section class="example-section">
      <h2>shallowReadonly 示例</h2>
      <p>shallowReadonly 创建一个只读的响应式代理，但只对顶层属性是只读的，深层嵌套对象不是只读的。</p>
      
      <div class="state-display">
        <h3>原始状态 (可变):</h3>
        <pre>{{ JSON.stringify(originalShallowState, null, 2) }}</pre>
        
        <h3>shallowReadonly 状态 (顶层只读):</h3>
        <pre>{{ JSON.stringify(shallowReadonlyState, null, 2) }}</pre>
        
        <div class="controls">
          <button @click="modifyOriginalShallow">修改原始状态</button>
          <button @click="tryModifyShallowReadonly">尝试修改shallowReadonly顶层</button>
          <button @click="tryModifyShallowReadonlyNested">尝试修改shallowReadonly嵌套对象</button>
        </div>
      </div>
    </section>

    <!-- 对比表 -->
    <section class="comparison-section">
      <h2>readonly vs shallowReadonly 对比</h2>
      <table class="comparison-table">
        <thead>
          <tr>
            <th>特性</th>
            <th>readonly</th>
            <th>shallowReadonly</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>顶层属性</td>
            <td>只读</td>
            <td>只读</td>
          </tr>
          <tr>
            <td>嵌套对象</td>
            <td>只读</td>
            <td>可变</td>
          </tr>
          <tr>
            <td>性能</td>
            <td>较低（深度处理）</td>
            <td>较高（仅顶层）</td>
          </tr>
          <tr>
            <td>适用场景</td>
            <td>完全不可变的数据</td>
            <td>防止顶层修改，允许内部修改</td>
          </tr>
        </tbody>
      </table>
    </section>

    <!-- 控制台输出区域 -->
    <section class="console-section">
      <h2>控制台输出</h2>
      <div class="console-output">
        <p v-for="(log, index) in logs" :key="index" :class="log.type">{{ log.message }}</p>
      </div>
      <button @click="clearLogs" class="clear-btn">清空日志</button>
    </section>
  </div>
</template>

<script setup>
import { reactive, readonly, shallowReadonly,ref } from 'vue'

// readonly 示例数据
const originalState = reactive({
  name: 'John',
  age: 30,
  address: {
    city: 'Beijing',
    street: 'Changan Street',
    details: {
      building: 'A栋',
      room: '101'
    }
  },
  hobbies: ['reading', 'swimming']
})

const readonlyState = readonly(originalState)

// shallowReadonly 示例数据
const originalShallowState = reactive({
  name: 'Jane',
  age: 25,
  address: {
    city: 'Shanghai',
    street: 'Nanjing Road',
    details: {
      building: 'B栋',
      room: '202'
    }
  },
  preferences: {
    theme: 'dark',
    language: 'en'
  }
})

const shallowReadonlyState = shallowReadonly(originalShallowState)

// 日志记录
const logs = ref([])

const log = (message, type = 'info') => {
  logs.value.push({ message, type })
  // 滚动到底部
  setTimeout(() => {
    const consoleDiv = document.querySelector('.console-output')
    if (consoleDiv) {
      consoleDiv.scrollTop = consoleDiv.scrollHeight
    }
  }, 100)
}

// readonly 相关操作
const modifyOriginal = () => {
  originalState.name = `Updated ${Date.now()}`
  originalState.age += 1
  originalState.address.city = 'Guangzhou'
  log('原始状态已修改', 'success')
}

const tryModifyReadonly = () => {
  try {
    readonlyState.name = 'Should not work'
    log('修改 readonly 顶层属性 - 意外成功', 'error')
  } catch (e) {
    log(`修改 readonly 顶层属性失败: ${e.message}`, 'error')
  }
}

const tryModifyReadonlyNested = () => {
  try {
    readonlyState.address.city = 'Should not work'
    log('修改 readonly 嵌套对象 - 意外成功', 'error')
  } catch (e) {
    log(`修改 readonly 嵌套对象失败: ${e.message}`, 'error')
  }
}

// shallowReadonly 相关操作
const modifyOriginalShallow = () => {
  originalShallowState.name = `Updated ${Date.now()}`
  originalShallowState.age += 1
  originalShallowState.address.city = 'Shenzhen'
  log('原始 shallow 状态已修改', 'success')
}

const tryModifyShallowReadonly = () => {
  try {
    shallowReadonlyState.name = 'Should not work'
    log('修改 shallowReadonly 顶层属性 - 意外成功', 'error')
  } catch (e) {
    log(`修改 shallowReadonly 顶层属性失败: ${e.message}`, 'error')
  }
}

const tryModifyShallowReadonlyNested = () => {
  try {
    // 这个操作实际上会成功，因为嵌套对象不是只读的
    shallowReadonlyState.address.city = 'Modified by nested access'
    log('成功修改 shallowReadonly 嵌套对象 - 这是预期行为', 'warn')
  } catch (e) {
    log(`修改 shallowReadonly 嵌套对象失败: ${e.message}`, 'error')
  }
}

const clearLogs = () => {
  logs.value = []
}
</script>

<style scoped>
.container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}

h1 {
  text-align: center;
  color: #2c3e50;
  margin-bottom: 30px;
}

.example-section {
  background: #f8f9fa;
  margin: 20px 0;
  padding: 25px;
  border-radius: 8px;
  box-shadow: 0 2px 10px rgba(0,0,0,0.05);
}

h2 {
  color: #34495e;
  margin-top: 0;
  border-bottom: 2px solid #3498db;
  padding-bottom: 10px;
}

h3 {
  color: #2c3e50;
  margin-top: 20px;
  margin-bottom: 10px;
}

pre {
  background: #2c3e50;
  color: #ecf0f1;
  padding: 15px;
  border-radius: 4px;
  overflow-x: auto;
  margin: 10px 0;
  font-size: 14px;
  line-height: 1.5;
}

.controls {
  margin: 20px 0;
}

button {
  background: #3498db;
  color: white;
  border: none;
  padding: 10px 15px;
  margin: 5px;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.3s ease;
  font-size: 14px;
}

button:hover {
  background: #2980b9;
  transform: translateY(-2px);
  box-shadow: 0 4px 8px rgba(0,0,0,0.1);
}

.comparison-section {
  margin: 30px 0;
  padding: 25px;
  background: #e8f4fc;
  border-radius: 8px;
}

.comparison-table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 15px;
  background: white;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}

.comparison-table th,
.comparison-table td {
  padding: 12px;
  text-align: left;
  border-bottom: 1px solid #ddd;
}

.comparison-table th {
  background: #3498db;
  color: white;
  font-weight: bold;
}

.comparison-table tr:nth-child(even) {
  background: #f8f9fa;
}

.comparison-table tr:hover {
  background: #e3f2fd;
}

.console-section {
  margin: 30px 0;
  padding: 25px;
  background: #2c3e50;
  border-radius: 8px;
  color: white;
}

.console-output {
  background: #1a252f;
  padding: 15px;
  border-radius: 4px;
  height: 200px;
  overflow-y: auto;
  margin: 15px 0;
  font-family: monospace;
  font-size: 14px;
}

.console-output .success {
  color: #2ecc71;
}

.console-output .error {
  color: #e74c3c;
}

.console-output .warn {
  color: #f39c12;
}

.clear-btn {
  background: #e74c3c;
}

.clear-btn:hover {
  background: #c0392b;
}

.state-display {
  margin: 15px 0;
}
</style>



